package cn.sell.comm.lock.service.impl;

import cn.sell.comm.lock.annotation.EasyLock;
import cn.sell.comm.lock.helper.LockInfoHelper;
import cn.sell.comm.lock.model.EasyLockInfo;
import cn.sell.comm.lock.model.LockType;
import cn.sell.comm.lock.service.Lock;
import org.aspectj.lang.ProceedingJoinPoint;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhumaer
 * @desc 锁工厂
 * @since 6/27/2018 11:29 PM
 */
public class LockFactory {

    /**
     * RedissonClient中提供了好多种锁，还有其它很多实用的方法
     */
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private LockInfoHelper lockInfoProvider;

    private static final Map<LockType, Lock> lockMap = new HashMap<>();

    /**
     * @PostConstruct该注解被用来修饰一个非静态的void（）方法。 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行，
     * 并且只会被服务器执行一次。PostConstruct在构造函数之后执行，init（）方法之前执行。
     */
    @PostConstruct
    public void init() {
        lockMap.put(LockType.Reentrant, new ReentrantLock(redissonClient));
        lockMap.put(LockType.Fair, new FairLock(redissonClient));
        lockMap.put(LockType.Read, new ReadLock(redissonClient));
        lockMap.put(LockType.Write, new WriteLock(redissonClient));
    }

    public Lock getLock(ProceedingJoinPoint joinPoint, EasyLock easyLock) {
        EasyLockInfo easyLockInfo = lockInfoProvider.get(joinPoint, easyLock);
        return lockMap.get(easyLockInfo.getType()).setLockInfo(easyLockInfo);
    }

}
